package com.example.demo;

import com.sun.xml.internal.ws.developer.Serialization;
import org.apache.ibatis.annotations.Mapper;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.Topic;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.transaction.PlatformTransactionManager;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.time.Duration;

@EnableCaching
@MapperScan(basePackages = "com.example.demo.mapper")
@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    // 注入事务管理器，它由springboot自动生成
//    @Autowired
//    PlatformTransactionManager transactionManager = null;

    // 使用后初始化方法，观察自动生成的事务管理器
//    @PostConstruct
//    public void viewTransactionManager(){
//        // 启动前加入断点观测
//        System.out.println(transactionManager.getClass().getName());
//    }
/*
    @Autowired
    private RedisTemplate redisTemplate = null;

    // Redis连接工厂
    @Autowired
    private RedisConnectionFactory redisConnectionFactory = null ;

    // Redis消息监听器
    @Autowired
    private MessageListener redisMsgListener = null;

    // 线程池
    @Autowired
    private ThreadPoolTaskScheduler taskScheduler = null;


    @Bean
    public ThreadPoolTaskScheduler initTaskScheduler(){
        if (taskScheduler != null){
            return taskScheduler;
        }
        taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(20);
        return taskScheduler;
    }

    @Bean
    public RedisMessageListenerContainer initRedisContaner(){
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        // Redis连接工厂
        container.setConnectionFactory(redisConnectionFactory);
        // 设置运行任务池
        container.setTaskExecutor(taskScheduler);
        // 定义监听渠道
        Topic topic = new ChannelTopic("topic1");
        container.addMessageListener(redisMsgListener, topic);
        return container;
    }

 */

    // 连接工厂
    @Autowired
    private RedisConnectionFactory connectionFactory = null;

    @Autowired
    private RedisTemplate redisTemplate = null;

    // 自定义初始化
    @PostConstruct
    public void init() {
        initRedisTemplate();
    }

    // 改变RedisTemplate对于键序列化策略
    private void initRedisTemplate() {
        RedisSerializer serializer = redisTemplate.getStringSerializer();
        redisTemplate.setKeySerializer(serializer);
        redisTemplate.setHashKeySerializer(serializer);
    }

    /**
     * 自定义Redis缓存管理器
     * <P>
     *        这里首先注入了RedisConnectionFactory连接工厂对象，该对象由Spring boot自动生成，
     *     在创建Redis缓存管理器对象RedisCacheManager的时候，首先创建了带锁的RedisCacheWrite对象，
     *     然后使用RedisCacheConfiguration对其属性进行配置，这里设置了禁用前缀，并且超时时间为10min；
     *     最后就通过RedisCacheWrite加锁写入器对象和RedisCacheManager对象去构建RedisCahceManager
     *     对象了，这样就完成了Redis缓存管理器的定义。
     * </P>
     * @return Redis缓存管理器
     */
    @Bean(name = "redisCacheManager")
    public RedisCacheManager initRedisCacheManager() {
        // Redis 加锁的写入器
        RedisCacheWriter writer = RedisCacheWriter.lockingRedisCacheWriter(connectionFactory);
        // 启动Redis 缓存的默认设置
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        // 设置jdk序列化器
        config.serializeValuesWith(
                RedisSerializationContext.SerializationPair.fromSerializer(
                        new JdkSerializationRedisSerializer()));
        // 禁用前缀
        config = config.disableKeyPrefix();
        // 设置10min超时
        config.entryTtl(Duration.ofMinutes(10));
        // 创建Redis缓存管理器
        RedisCacheManager redisCacheManager = new RedisCacheManager(writer, config);
        return redisCacheManager;
    }


}
